package com.astrocsr.dao;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.astrocsr.common.db.DBUtils;
import com.astrocsr.common.db.SearchQueryTemplate;
import com.astrocsr.domain.db.SearchResult;

public class BaseHelperDAO {
	
	static final Logger log = Logger.getLogger(BaseHelperDAO.class);
	
	@Autowired
	private SessionFactory sessionFactory;
	private HibernateTemplate hibernateTemplate;
	
	public Session getCurrentSession () {
		return this.sessionFactory.getCurrentSession();
	}
	
	public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

	@SuppressWarnings("unchecked")
	public <T> SearchResult<T> find(final SearchQueryTemplate searchQueryTemplate) {
		final String LOCATION = "find(SearchQueryTemplate searchQueryTemplate)";

	       try {
	           SearchResult<T> result = new SearchResult<T>();

	           if (log.isDebugEnabled())
	               log.debug(LOCATION + " -->>> pagingInfo" + searchQueryTemplate.getPagingInfo());

	           // +++ perform search
	           Query query = searchQueryTemplate.getQuery(getCurrentSession());
	           // add paging
	           DBUtils.addPaging(query, searchQueryTemplate.getPagingInfo());
	           List<T> listRs = query.list();
	            
	           if (listRs != null) {
	               result.addAll(listRs);
	           }

	           // +++ perform count
	           Query queryTotal = searchQueryTemplate.getCountQuery(getCurrentSession());
	           Object objTotal = queryTotal.uniqueResult();

	           DBUtils.setTotalValue(searchQueryTemplate.getPagingInfo(), objTotal);
	           result.setPagingInfo(searchQueryTemplate.getPagingInfo());

	           if (log.isDebugEnabled())
	               log.debug(LOCATION + ":: END");
	           return result;
	       } catch (RuntimeException re) {
	           log.error(LOCATION, re);
	           throw re;
	       }
	}
	
	@SuppressWarnings("unchecked")
	public <T> T uniqueResult(final SearchQueryTemplate searchQueryTemplate) {
		final String LOCATION = "uniqueResult(SearchQueryTemplate searchQueryTemplate)";
		T result = null;
		try {
	
			if (log.isDebugEnabled())
				log.debug(LOCATION + " -->>> pagingInfo" + searchQueryTemplate.getPagingInfo());
	
			// +++ perform search
			Query query = searchQueryTemplate.getQuery(getCurrentSession());
			query.setMaxResults(1);
			
			result = (T)query.uniqueResult();

	   if (log.isDebugEnabled())
	       log.debug(LOCATION + ":: END");
	       return result;
	   } catch (RuntimeException re) {
	       log.error(LOCATION, re);
	       throw re;
	   }
	}
}
